package com.wjl.maker.generator.main;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import com.wjl.maker.generator.JarGenerator;
import com.wjl.maker.generator.ScriptGenerator;
import com.wjl.maker.generator.file.DynamicFileGenerator;
import com.wjl.maker.meta.Meta;
import com.wjl.maker.meta.MetaManager;
import com.wjl.maker.meta.MetaValidator;
import freemarker.template.TemplateException;

import java.io.File;
import java.io.IOException;
import java.util.List;

public class GenerateTemplate {

    public  void doGenerate() throws TemplateException, IOException, InterruptedException{
        Meta meta = MetaManager.getMeta();
        MetaValidator.doValidAndFill(meta);
        String projectPath = System.getProperty("user.dir");
        String outputPath = projectPath + File.separator + "generated";
        doGenerate(meta, outputPath);

    }
    public  void doGenerate( Meta meta, String outputPath) throws TemplateException, IOException, InterruptedException{
        if (!FileUtil.exist(outputPath)) {
            FileUtil.mkdir(outputPath);
        }

        String sourceCopyDest = copySourceCode(meta, outputPath);

        generateCode(meta, outputPath);

        String jarPath=buildJar(outputPath,meta);

        String shellOutputFilePath=BuildScript(outputPath,jarPath);

        buildDist(outputPath, jarPath, sourceCopyDest, shellOutputFilePath);

    }

    protected String buildDist(String outputPath, String jarPath, String sourceCopyDest, String shellOutputFilePath) {
        String distPath = outputPath + "-dist";
        String targetJarAbsolutePath=distPath+File.separator+"target";
        FileUtil.mkdir(targetJarAbsolutePath);
        String jarAbsolutePath= outputPath +File.separator+ jarPath;
        FileUtil.copy(jarAbsolutePath,targetJarAbsolutePath,true);
        FileUtil.copy(sourceCopyDest,distPath,true);
        FileUtil.copy(shellOutputFilePath,distPath,true);
        return distPath;
    }

    protected String buildJar(String outputPath,Meta meta) throws IOException, InterruptedException {
        String jarName = String.format("%s-%s-jar-with-dependencies.jar", meta.getName(), meta.getVersion());
        String jarPath = "target/" + jarName;
        JarGenerator.doGenerate(outputPath);
        return jarPath;
    }

    protected String buildZip(String sourcePath){
        String zipPath=sourcePath+".zip";
        ZipUtil.zip(sourcePath,zipPath);
        return zipPath;
    }

    protected String BuildScript(String outputPath,String jarPath) throws IOException {
        String shellOutputFilePath = outputPath + File.separator + "generator";
        ScriptGenerator.doGenerate(shellOutputFilePath,jarPath);
        return shellOutputFilePath;
    }


    protected void generateCode(Meta meta, String outputPath) throws IOException, TemplateException {
        String resourceAbsolutePath = "";
        List<String> split = StrUtil.split(meta.getBasePackage(), '.');
        String outPutBasePackage = StrUtil.join("/", split);
        String outputBaseJavaPath= outputPath + File.separator +"src/main/java/"+ outPutBasePackage;
        String inputFilePath;
        String outputFilePath;
        inputFilePath=resourceAbsolutePath+File.separator + "templates/java/model/DataModel.java.ftl";
        outputFilePath=outputBaseJavaPath+File.separator+"model/DataModel.java";
        DynamicFileGenerator.doGenerate(inputFilePath,outputFilePath, meta);

        inputFilePath=resourceAbsolutePath+File.separator + "templates/java/cli/command/ConfigCommand.java.ftl";
        outputFilePath=outputBaseJavaPath+File.separator+"cli/command/ConfigCommand.java";
        DynamicFileGenerator.doGenerate(inputFilePath,outputFilePath, meta);

        inputFilePath=resourceAbsolutePath+File.separator + "templates/java/cli/command/ListCommand.java.ftl";
        outputFilePath=outputBaseJavaPath+File.separator+"cli/command/ListCommand.java";
        DynamicFileGenerator.doGenerate(inputFilePath,outputFilePath, meta);

        // cli.command.JsonGenerateCommand
        inputFilePath = resourceAbsolutePath +File.separator + "templates/java/cli/command/JsonGenerateCommand.java.ftl";
        outputFilePath = outputBaseJavaPath + File.separator + "/cli/command/JsonGenerateCommand.java";
        DynamicFileGenerator.doGenerate(inputFilePath , outputFilePath, meta);

        inputFilePath=resourceAbsolutePath +File.separator+ "templates/java/generator/file/MainGenerator.java.ftl";
        outputFilePath=outputBaseJavaPath+File.separator+"generator/file/MainGenerator.java";
        DynamicFileGenerator.doGenerate(inputFilePath,outputFilePath, meta);

        inputFilePath=resourceAbsolutePath+File.separator + "templates/java/cli/command/GenerateCommand.java.ftl";
        outputFilePath=outputBaseJavaPath+File.separator+"cli/command/GenerateCommand.java";
        DynamicFileGenerator.doGenerate(inputFilePath,outputFilePath, meta);

        inputFilePath=resourceAbsolutePath +File.separator+ "templates/java/cli/CommandExecutor.java.ftl";
        outputFilePath=outputBaseJavaPath+File.separator+"cli/CommandExecutor.java";
        DynamicFileGenerator.doGenerate(inputFilePath,outputFilePath, meta);

        inputFilePath=resourceAbsolutePath+File.separator + "templates/java/generator/file/DynamicFileGenerator.java.ftl";
        outputFilePath=outputBaseJavaPath+File.separator+"generator/file/DynamicFileGenerator.java";
        DynamicFileGenerator.doGenerate(inputFilePath,outputFilePath, meta);



        inputFilePath=resourceAbsolutePath +File.separator+ "templates/java/generator/file/StaticFileGenerator.java.ftl";
        outputFilePath=outputBaseJavaPath+File.separator+"generator/file/StaticFileGenerator.java";
        DynamicFileGenerator.doGenerate(inputFilePath,outputFilePath, meta);

        inputFilePath=resourceAbsolutePath+File.separator + "templates/java/Main.java.ftl";
        outputFilePath=outputBaseJavaPath+File.separator+"Main.java";
        DynamicFileGenerator.doGenerate(inputFilePath,outputFilePath, meta);

        inputFilePath=resourceAbsolutePath+File.separator + "templates/pom.xml.ftl";
        outputFilePath= outputPath +File.separator+"pom.xml";
        DynamicFileGenerator.doGenerate(inputFilePath,outputFilePath, meta);

        inputFilePath=resourceAbsolutePath+File.separator + "templates/README.md.ftl";
        outputFilePath= outputPath +File.separator+"README.md";
        DynamicFileGenerator.doGenerate(inputFilePath,outputFilePath, meta);
    }

    protected String copySourceCode(Meta meta, String outputPath) {
        String sourceRootPath= meta.getFileConfig().getSourceRootPath();
        String sourceCopyDest= outputPath +File.separator+".source";
        FileUtil.copy(sourceRootPath,sourceCopyDest,false);
        return sourceCopyDest;
    }


}
